package com.sz.common.pay.pingan.core.client;

import com.sz.common.pay.common.PayLogger;
import com.sz.common.pay.pingan.constant.Constant;
import com.sz.common.pay.pingan.constant.ResponseCode;
import com.sz.common.pay.pingan.exception.NoAvailableConnectException;
import com.sz.common.pay.pingan.exception.OperationFailedException;
import com.sz.common.pay.pingan.exception.PayCommonException;
import com.sz.common.pay.pingan.util.PayExceptionUtil;

import java.util.HashMap;

/**
 * Function: 封装请求与响应过程，进行对象操作 <br>
 * @author: siqishangshu <br>
 * @date: 2017-10-27 20:38:00
 */
public class PAPay {

    private static PayLogger payLogger = PayLogger.getLogger(PAPay.class);
    private static TcpRequestConverter requestMessageConverter = new TcpRequestConverter();
    private static TcpResponseConverter responseMessageConverter = new TcpResponseConverter();

    /**
     * 封装请求与响应过程，进行对象操作
     *
     * @param request
     * @param responseClazz
     * @return response
     * @throws NoAvailableConnectException 没用可以链接
     * @throws OperationFailedException    操作失败返回结果
     * @throws PayCommonException
     */
    public static Object sendMessage(String thirdLogNo, Object request, Class responseClazz) throws NoAvailableConnectException, OperationFailedException, PayCommonException {

        isVaildParam(request, responseClazz, thirdLogNo);
        /**
         * 第一部分：生成发送银行的请求的报文的实例
         */
        //使用属性，一一拼接
        //调用函数生成报文
        String tranMessage = requestMessageConverter.getTranMessage(ClientMapConverter.toMap(request, thirdLogNo));
        /*输出报文结果*/
        payLogger.info(thirdLogNo, "-------------------------------");
        payLogger.info(thirdLogNo, "第一部分：生成发送银行的请求的报文的实例");
        payLogger.info(thirdLogNo, "request:" + request.toString());
        payLogger.info(thirdLogNo, "tranMessage:" + tranMessage);

        HashMap responseMap = new HashMap();
        /**
         * 第二部分：获取银行返回的报文的实例
         *
         */
            /*发送请求报文*/
        PAClient.doSend(thirdLogNo, tranMessage, responseMap);

            /*获取银行返回报文*/
        //银行返回的报文
        String recvMessage = (String) responseMap.get(Constant.RECIVE_MESSAGE);
            /*输出报文结果*/
        payLogger.info(thirdLogNo, "第二部分：获取银行返回的报文");
        payLogger.info(thirdLogNo, recvMessage);
        payLogger.info(thirdLogNo, "-------------------------------");
        /**
         * 第三部分：解析银行返回的报文的实例
         *
         */

        //使用属性一一拼接
        Object response = ClientMapConverter.toObj(thirdLogNo, responseMessageConverter.parsingTranMessage(thirdLogNo, recvMessage), responseClazz);

        /*输出报文结果*/
        payLogger.info(thirdLogNo, "第三部分：解析银行返回的报文");
        payLogger.info(thirdLogNo, "response：" + response.toString());
        payLogger.info(thirdLogNo, "-------------------------------");
        return response;
    }


    public static String getSignMessage(String thirdLogNo, Object request) throws PayCommonException {
        isVaildParam(request, thirdLogNo);
        return requestMessageConverter.getSignMessage(ClientMapConverter.toMap(request, thirdLogNo));
    }


    private static void isVaildParam(Object request, String thirdLogNo) throws PayCommonException {
        if (null == request) {
            PayExceptionUtil.throwPayCommonException("request can't be null", ResponseCode.ERR030);
        }

        if (!request.getClass().getPackage().toString().contains(Constant.VAILD_PACKAGE)) {
            PayExceptionUtil.throwPayCommonException("request is not a vaild object", ResponseCode.ERR947);
        }

        if ((thirdLogNo.length() != Constant.THIRD_LOG_NO_LEN)) {
            PayExceptionUtil.throwPayCommonException("thirdLogNo is not a vaild value", ResponseCode.ERR935);
        }
    }

    private static void isVaildParam(Object request, Class responseClazz, String thirdLogNo) throws PayCommonException {
        if (null == request) {
            PayExceptionUtil.throwPayCommonException("request can't be null", ResponseCode.ERR030);
        }
        if (null == responseClazz) {
            PayExceptionUtil.throwPayCommonException("responseClazz can't be null", ResponseCode.ERR947);
        }

        if (!request.getClass().getPackage().toString().contains(Constant.VAILD_PACKAGE)) {
            PayExceptionUtil.throwPayCommonException("request is not a vaild object", ResponseCode.ERR030);
        }
        if (!responseClazz.getPackage().toString().contains(Constant.VAILD_PACKAGE)) {
            PayExceptionUtil.throwPayCommonException("responseClazz is not a vaild clazz", ResponseCode.ERR947);
        }
        if ((thirdLogNo.length() != Constant.THIRD_LOG_NO_LEN)) {
            PayExceptionUtil.throwPayCommonException("thirdLogNo is not a vaild value", ResponseCode.ERR935);
        }
    }
}
